/*
 *         (C) COPYRIGHT Ingenic Limited
 *              ALL RIGHT RESERVED
 *
 * File        : uranus_tensor.h
 * Authors     :
 * Create Time : 2020-08-04 14:58:26 (CST)
 * Description : tensor of api
 *
 */

#ifndef __MAGIK_URANUS_CORE_TENSOR_H__
#define __MAGIK_URANUS_CORE_TENSOR_H__

#include "common/common_def.h"
#include "common/common_type.h"
#include <initializer_list>
#include <stdint.h>
#include <stdio.h>
#include <vector>

namespace magik {
namespace uranus {
ALG_PACK_START
using shape_t = std::vector<int32_t>;
typedef shape_t Shape;
class URANUS_API Tensor {
public:
    /*dev: Device::CPU or Device::EXT_CPU*/
    Tensor(shape_t shape, DataType data_type = DataType::UINT8, DataFormat fmt = DataFormat::NHWC,
           Device dev = Device::CPU);
    /*deep: true, deep copy constructor
     *      false, shallow copy contructor
     */
    /* Tensor(const Tensor &t, bool deep = false); */
    /*for ai compiler
     *TODO:delete
     */
    /*shallow copy constructor*/
    Tensor(const Tensor &t);
    Tensor &operator=(const Tensor &t);
    Tensor(void *tsx);
    ///*for ai compiler
    // *TODO:delete
    // */
    // Tensor(const void *tsx);
    /*for ai compiler
     *default Device is Device::CPU
     *default DataType is DataType::INT8
     *default DataFormat is DataFormat::NHWC
     */
    Tensor();
    virtual ~Tensor();

    shape_t shape() const;
    DataType data_type() const;
    DataFormat data_format() const;
    void reshape(shape_t &shape) const;
    void reshape(std::initializer_list<int32_t> shape) const;
    template <typename T>
    const T *vdata() const;
    template <typename T>
    const T *pdata() const;
    template <typename T>
    T *mudata() const;
    void free_data() const;
    /*vdata, pdata, bytes_size is set
     *Device is changed into Device::EXT_CPU
     */
    int set_data(void *vdata, void *pdata, size_t bytes_size);
    void *get_tsx() const; /*for internal*/
    int step(int dim) const;
    int get_bytes_size() const;
    void set_dim_align(int dim, int align);

    void *tensort = NULL;

private:
    int *ref_count = NULL;
#ifndef URANSU_COMPILE_CORE
public:
    void set_data_type(DataType data_type) const;
    void set_data_format(DataFormat fmt) const;
    int get_dim_align(int dim);
#endif
};
ALG_PACK_END
} // namespace uranus
} // namespace magik

#endif /* __MAGIK_URANUS_CORE_TENSOR_H__ */
